package clam.apps.adu.metier;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * 
 */

/**
 * @author AlexL
 */
public class ClassManager
{
	private Class<?>	c_class;
	private Object		o_obj;
	
	/**
	 * @param o
	 */
	public ClassManager(Object o)
	{
		this.o_obj = o;
		this.c_class = o.getClass();
	}
	
	public ArrayList<String> fieldsName()
	{
		Field[] fields = this.c_class.getDeclaredFields();
		ArrayList<String> stringFields = new ArrayList<String>();
		
		for (Field field : fields)
		{
			field.setAccessible(true);
			stringFields.add(field.getName());
		}
		
		return stringFields;
	}
	
	public HashMap<String, String> fieldsTagName()
	{
		ArrayList<String> fields = this.fieldsName();
		HashMap<String, String> fieldsTags = new HashMap<String, String>();
		
		for (String s : fields)
			if (s.startsWith("TAG_"))
			{
				String field = s.substring(4).toLowerCase();
				String value = (String) this.get(field, true);
				fieldsTags.put(field, value);
			}
		
		return fieldsTags;
	}
	
	/**
	 * Fonction permettant de récupérer la valeur de l'attribu passer en
	 * paramêtre
	 * 
	 * @param field
	 *            l'attribue que l'on souhaite récupérer
	 * @return
	 */
	public Object get(String field, boolean isTag)
	{
		Method getter;
		String methode = "get" + ((isTag) ? "Tag" : "")
				+ field.substring(0, 1).toUpperCase()
				+ field.substring(1).toLowerCase();
		
		try
		{
			getter = this.c_class.getDeclaredMethod(methode);
			getter.setAccessible(true);
			
			return getter.invoke(this.o_obj);
		}
		catch (NoSuchMethodException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (IllegalAccessException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (IllegalArgumentException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (InvocationTargetException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}
	
	/**
	 * Fonction permettant de d'attribuer un valeur en fonction du nom de
	 * l'attribu.
	 * 
	 * @param field
	 *            l'attribu de la classe
	 * @param value
	 *            la valeur a lui attribuer
	 */
	public void set(String field, Object value)
	{
		Method setter;
		String methode = "set" + field.substring(0, 1).toUpperCase()
				+ field.substring(1).toLowerCase();
		
		try
		{
			// if (field.contains("date"))
			// {
			// long timestamp = Long.valueOf((String) value).longValue() *
			// 1000L;
			// value = new Date(timestamp);
			// }
			
			setter = this.c_class.getDeclaredMethod(methode, value.getClass());
			setter.setAccessible(true);
			setter.invoke(this.o_obj, value);
			
		}
		catch (NoSuchMethodException e)
		{
			e.printStackTrace();
		}
		catch (IllegalAccessException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (IllegalArgumentException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (InvocationTargetException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * @return the c_class
	 */
	public Class<?> getC_class()
	{
		return this.c_class;
	}
	
	/**
	 * @param c_class
	 *            the c_class to set
	 */
	public void setC_class(Class<?> c_class)
	{
		this.c_class = c_class;
	}
	
	/**
	 * @return the o_obj
	 */
	public Object getO_obj()
	{
		return this.o_obj;
	}
	
	/**
	 * @param o_obj
	 *            the o_obj to set
	 */
	public void setO_obj(Object o_obj)
	{
		this.o_obj = o_obj;
	}
}
